#include <filesystem>
#include <fstream>

#include "decoder.h"
#include "file.hpp"
#include "stdafx.h"

namespace fs = std::filesystem;

std::vector<std::string> TraversingFiles(std::string dirName = "./") {
    namespace fs = std::filesystem;
    std::vector<std::string> files = {};
    fs::path url(dirName);
    if (!fs::exists(url)) {
        return files;
    }

    fs::directory_entry input(url);
    if (input.status().type() != fs::file_type::directory) {
        return files;
    }

    fs::directory_iterator dir(url);
    for (auto v : dir) {
        if (fs::path(v).extension() != ".dat") continue;
        files.emplace_back(v.path().string());
    }
    return files;
}

void createPlyFile(const char* fileName, const lrr300::DecodedData& data) {
    pcl::PointCloud<pcl::PointXYZ> cloud;
    for (auto& p : data.data) {
        cloud.push_back(pcl::PointXYZ(p.x, p.y, p.z));
    }
    pcl::PLYWriter writer;
    writer.write(fileName, cloud);
    LOG(INFO) << "Finished." << std::endl;
}

void do_main(char** argv) {
    // lrr300::Decoder::decode(argv[1], [&](const lrr300::DecodedData& data) {
    //     LOG(INFO) << "Point Count = " << data.data.size();
    //     createPlyFile(fmt::format("{}", argv[2]).c_str(), data);
    // });

    auto paths = TraversingFiles(argv[1]);
    for (auto& path : paths) {
        LOG(INFO) << path;
        fs::path dir = fs::path(path).replace_extension("");
        LOG(INFO) << dir;
        if (!fs::exists(dir)) {
            fs::create_directories(dir);
        }
        // 北京 单帧
        lrr300::Decoder::decode_single_frame(path, [&](const lrr300::DecodedData& data) {
            static int sum = 0;
            sum += data.data.size();
            LOG(INFO) << "Current Frame Point Count = " << data.data.size() << ",total Frame Count = " << sum;
            createPlyFile(fmt::format("{}/{}.ply", dir.string(), data.frame_number).c_str(), data);
        });

        // 另一家厂商
        // hhfox::createDirIfNoExist(argv[2]);
        // lrr300::Decoder::decode_single_frame_v2(argv[1], [&](const lrr300::DecodedData2& data) {
        //     LOG(INFO) << "Point Count = " << data.data.size();
        //     std::ofstream out(fmt::format("{}/{}.ply", argv[2], data.frame_number), std::ios::out);
        //     for (auto& line : data.data) {
        //         out << line << '\n';
        //     }
        // });
    }
}

int main(int argc, char** argv) {
    // if (argc < 3) {
    //     fmt::print("usage: {} [原始数据文件名] [输出文件名]\n", argv[0]);
    //     return -1;
    // }
    if (argc < 2) {
        fmt::print("usage: {} [原始数据所在目录]\n", argv[0]);
        return -1;
    }
    Logging_Init(argv[0], "./logs");
    do_main(argv);
    Logging_Uninit();
    return 0;
}